// import * as $ from 'jquery'
import { Filesystem, Directory, Encoding } from '@capacitor/filesystem';
var map_location = 'cj' // 长江
var selectPointerMove
var selectMouseClick

var mapFalshMarker
var mapMeasureTool = {}
const exportOptions = {
  useCORS: true,
  ignoreElements: function (element) {
    const className = element.className || '';
    // return !(
    //   className.indexOf('ol-control') === -1 ||
    //   className.indexOf('ol-scale') > -1 ||
    //   (className.indexOf('ol-attribution') > -1 &&
    //     className.indexOf('ol-uncollapsible'))
    // );
  },
};
// let url='content://com.android.providers.downloads.documents/document/downloads'
// const readFilePath = async () => {
//   // Here's an example of reading a file with a full file path. Use this to
//   // read binary data (base64 encoded) from plugins that return File URIs, such as
//   // the Camera.
//   const contents = await Filesystem.readFile({
//     path: 'content://com.android.providers.downloads.documents/document/downloads'
//   });

//   alert('data:', contents);
//   return contents
// };
// readFilePath()

// alert(JSON.stringify(Directory.Documents))
// var pageName
let url = './tdt'
var cj = {
  minZoom: 0,
  maxZoom: 20,
  initialZoom: 6,
  minVisbleZoom: 5,
  minVisibleScale: 10000000, // 分级时，显示尺度
  minVisibleScale_: 10000000, // 未分级时，标注显示尺度(3000000)
  origin: [-180.0, 90.0],
  init_Center: [107.5, 30],
  full_Extent: {
    xmin: 73.498436,
    ymin: 21.142454,
    xmax: 135.086655,
    ymax: 53.561573
  },
  init_Extent: {
    // xmin: 90.51758618252902,
    // ymin: 23.893409685015925,
    // xmax: 121.95764914055758,
    // ymax: 36.12653381334954
  },
  isClassify: false, // 是否分级显示
  isTextVisble: true, // 是否显示站名
  resolutions: [
    0.7031250000029744,
    0.35156250000000011,
    0.17578125000000006,
    0.087890625000000028,
    0.043945312500000014,
    0.021972656250000007,
    0.010986328125000003,
    0.0054931640625000017,
    0.0027465820312500009,
    0.0013732910156250004,
    0.00068664550781250022,
    0.00034332275390625011,
    0.00017166137695312505,
    8.5830688476562527E-5,
    4.2915344238281264E-5,
    2.1457672119140632E-5,
    1.0728836059570316E-5,
    5.3644180297851579E-6,
    2.68220901489257E-6,
    1.3411118121060625E-6
  ],
  basemap_config: [
    {
      map_url: [{
        // map_url: mapList.yxt+'https://t0.tianditu.gov.cn/img_c/wmts?tk=3a680258ba5307c21c4a85b362c59060',
        map_url: url+'/{x}/{y}/{z}.png',
        type: 'xyz',
        name: 'haitu',
        zIndex: 0,
        id: 'img_c'
      }, {
        // map_url: 'http://t0.tianditu.com/cta_c/wmts?tk=3a680258ba5307c21c4a85b362c59060',
        map_url: url+'/{x}/{y}/{z}.png',
        type: 'xyz',
        name: '标注图层',
        zIndex: 99,
        id: 'cta_c'
      }],
      url: 'images/yxt.png',
      name: '二维卫星',
      visible: true,
      id: 'map1'
    }
  ]
}
var map_config = {
  cj: cj
}
var baseMapLayersConfig = map_config[map_location].basemap_config
var dynamicLayers = {}

var areaDrawTool = {}
var lineDrawTool = {}
var pointDrawTool = {}
var squareDrawTool = {}
var circleDrawTool = {}
import Map from 'ol/Map'
import Overlay from 'ol/Overlay'

import {
  TileArcGISRest
} from 'ol/source'
import {
  getVectorContext
} from 'ol/render';
import {
  easeOut
} from 'ol/easing';
import TileLayer from 'ol/layer/Tile'
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import Feature from 'ol/Feature'
import XYZ from 'ol/source/XYZ'
import TileWMS from 'ol/source/TileWMS';
import {
  ImageArcGISRest
} from 'ol/source'
import OSM from 'ol/source/OSM'
import ImageLayer from 'ol/layer/Image'
import Static from 'ol/source/ImageStatic'
import View from 'ol/View'
import Projection from 'ol/proj/Projection'
import {
  get as getProjection
} from 'ol/proj'

import WMTS from 'ol/source/WMTS'
import {
  Circle as CircleStyle,
  Fill,
  Stroke,
  Style
} from 'ol/style'
import {
  defaults as defaultControls
} from 'ol/control'
import MousePosition from 'ol/control/MousePosition'
import {
  createStringXY
} from 'ol/coordinate'
import WMTSTileGrid from 'ol/tilegrid/WMTS'
import {
  LineString,
  Point,
  Polygon
} from 'ol/geom'
import {
  Group as LayerGroup
} from 'ol/layer'
import {
  getTopLeft,
  getWidth,
  getCenter
} from 'ol/extent'
import Select from 'ol/interaction/Select'
import {
  pointerMove
} from 'ol/events/condition'
import {
  getLength,
  getArea
} from 'ol/sphere'
import {
  Draw
} from 'ol/interaction'
import Collection from 'ol/Collection'
import {
  unByKey
} from 'ol/Observable'
import {
  getRenderPixel
} from 'ol/render'
import {
  createBox
} from 'ol/interaction/Draw'
import {
  fromCircle
} from 'ol/geom/Polygon';
import Circle from 'ol/geom/Circle';
const selectedFeatures = new Collection() // 避免一个要素多次点击无效的问题

export default class OlMap {

  // 地图初始化  projection: 'EPSG:4326'
  initMap(id, epsg = 'EPSG:4326', event, unit, center) {
    const _this = this
    this.dynamicLayers = {}
    this.baseMapLayers = new Map()
    this.mapView = null
    var grouplayers = []
    this.unit = unit
    // for (var i = 0; i < baseMapLayersConfig.length; i++) {
    //   var v = baseMapLayersConfig[i]
    //   if (Array.isArray(v.map_url)) {
    //     var layers = []
    //     for (var ii = 0; ii < v.map_url.length; ii++) {
    //       var vv = v.map_url[ii]
    //       if (vv.type === 'tdt') {
    //         vv.layer = _this.getTiledLayer(vv.id, vv.map_url, vv.zIndex)
    //       } else if (vv.type === 'arcgis') {
    //         vv.layer = _this.getTiledArcgisLayer(vv.id, vv.map_url, vv.zIndex)
    //       }else if (vv.type === 'xyz') {
    //         vv.layer = _this.getTiledXYZLayer(vv.id, vv.map_url, vv.zIndex)
    //       }
    //       layers.push(vv.layer)
    //     }
    //     v.layer = new LayerGroup({
    //       layers: layers,
    //       visible: v.visible
    //     })
    //     v.layer._id = v.id
    //   } else {
    //     if (v.type === 'tdt') {
    //       v.layer = _this.getTiledLayer(v.id, v.map_url, vv.zIndex)
    //     } else if (v.type === 'arcgis') {
    //       v.layer = _this.getTiledArcgisLayer(v.id, v.map_url, vv.zIndex)
    //     }
    //     v.layer.setVisible(v.visible)
    //   }
    //   grouplayers.push(v.layer)

    //   this.baseMapLayers.set(v.id, v.layer)
    // }
    // 点图层弹窗元素
    // $('#' + id).append('<div id="popup" class="ol-popup"><div id="popup-content" class="popup-content"></div></div>')
    // var container = $('#popup')[0]
    // 浮动层 弹窗
    // var overlay = new Overlay({
    //   id: 'popup',
    //   element: container,
    //   positioning: 'top-center',
    //   autoPan: false,
    //   autoPanAnimation: {
    //     duration: 250
    //   }
    // })
    const projection = new Projection({
      code: epsg,
      extent: event,
      units: unit,
    });

    this.mapView = new View({
      projection: projection,
      extent: event,
      zoom: 1,
      center: center,
      // zoom: map_config[map_location].initialZoom,
      // maxZoom: map_config[map_location].maxZoom,
      // minZoom: map_config[map_location].minZoom
    })
    this.osm = new TileLayer({
      source: new OSM({
        wrapX: false,
      })
    })
    // alert(JSON.stringify(Directory.Documents))
    // alert(Directory.Documents)
    grouplayers.push(this.osm)
    let url='content://com.android.providers.downloads.documents/document/downloads' +'/{x}/{y}/{z}.png'
    // let urldir = async () => {
    //    let contents = await Filesystem.getUri({
    //   path: 'download',
    //   directory: Directory.Documents,
    //   })
    //   return contents
    //   alert(contents)
    // };
    // alert(url)
    // let layers = [this.getTiledXYZLayer('ss', url, 3)]
    // let layer = new LayerGroup({
    //     layers: layers,
    //     visible: true
    //   })
    // grouplayers.push(layer)
    this.olmap = new Map({
      logo: false,
      target: id,
      layers: grouplayers,
      // overlays: [overlay],
      controls: defaultControls({
        attribution: false,
        zoom: false,
        rotate: false
      }).extend([
        new MousePosition({
          className: 'ol-mouse-pos',
          coordinateFormat: createStringXY(2),
          undefinedHTML: ''
        })
      ]),
      view: _this.mapView
    })
    // mouseover事件
    this.mapMouseover()
    // 点击事件
    // this.mapClick()

    mapMeasureTool.source = new VectorSource()
    mapMeasureTool.vector = new VectorLayer({
      source: mapMeasureTool.source,
      layerName: 'measureLayer',
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: '#ffcc33',
          width: 2
        }),
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({
            color: '#ffcc33'
          })
        })
      })
    })
    this.olmap.addLayer(mapMeasureTool.vector)
    areaDrawTool.source = new VectorSource()
    areaDrawTool.vector = new VectorLayer({
      source: areaDrawTool.source,
      zIndex: 2,
      layerName: 'areaDrawLayer',
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: '#ffcc33',
          width: 2
        }),
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({
            color: '#ffcc33'
          })
        })
      })
    })
    this.olmap.addLayer(areaDrawTool.vector)
    circleDrawTool.source = new VectorSource()
    circleDrawTool.vector = new VectorLayer({
      source: circleDrawTool.source,
      layerName: 'circleDrawLayer',
      zIndex: 2,

      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: '#ffcc33',
          width: 2
        }),
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({
            color: '#ffcc33'
          })
        })
      })
    })
    this.olmap.addLayer(circleDrawTool.vector)
    lineDrawTool.source = new VectorSource()
    lineDrawTool.vector = new VectorLayer({
      source: lineDrawTool.source,
      zIndex: 2,
      layerName: 'lineDrawLayer',
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: '#ffcc33',
          width: 2
        }),
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({
            color: '#ffcc33'
          })
        })
      })
    })
    this.olmap.addLayer(lineDrawTool.vector)
    pointDrawTool.source = new VectorSource()
    pointDrawTool.vector = new VectorLayer({
      source: pointDrawTool.source,
      layerName: 'pointDrawLayer',
      zIndex: 2,
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: '#ffcc33',
          width: 2
        }),
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({
            color: '#ffcc33'
          })
        })
      })
    })
    this.olmap.addLayer(pointDrawTool.vector)
    squareDrawTool.source = new VectorSource()
    squareDrawTool.vector = new VectorLayer({
      source: squareDrawTool.source,
      layerName: 'squareDrawLayer',
      zIndex: 2,
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: '#ffcc33',
          width: 2
        }),
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({
            color: '#ffcc33'
          })
        })
      })
    })
    this.olmap.addLayer(squareDrawTool.vector)
    mapMeasureTool.continuePolygonMsg = '点击继续绘制多边形'
    mapMeasureTool.continueLineMsg = '点击继续绘制线条'
  }

  // 点击闪烁点效果
  pointClok(_this, e) {
    const tileLayer = new TileLayer({
      source: new OSM({
        wrapX: false,
      }),
    });
    console.log('tilelayer', tileLayer)
    const source = new VectorSource({
      wrapX: false,
    });

    // const vector = new VectorLayer({
    //   source: source,
    // });
    // _this.olmap.addLayer(vector)
    _this.olmap.removeLayer(tileLayer)
    _this.olmap.addLayer(tileLayer)
    const addRandomFeature = () => {
      const geom = new Point([e.xField, e.yField]);
      const feature1 = new Feature(geom);
      source.addFeature(feature1);
    }

    const duration = 3000;
    const flash = (feature) => {
      const start = Date.now();
      const flashGeom = feature.getGeometry().clone();
      const listenerKey = tileLayer.on('postrender', animate);

      function animate(event) {
        const frameState = event.frameState;
        const elapsed = frameState.time - start;
        if (elapsed >= duration) {
          unByKey(listenerKey);
          return;
        }
        const vectorContext = getVectorContext(event);
        const elapsedRatio = elapsed / duration;
        // radius will be 5 at start and 30 at end.
        const radius = easeOut(elapsedRatio) * 25 + 5;
        const opacity = easeOut(1 - elapsedRatio);

        const style = new Style({
          image: new CircleStyle({
            radius: radius,
            stroke: new Stroke({
              color: 'rgba(255, 0, 0, ' + opacity + ')',
              width: 0.25 + opacity,
            }),
          }),
        });

        vectorContext.setStyle(style);
        vectorContext.drawGeometry(flashGeom);
        _this.olmap.render();
      }
    }

    source.on('addfeature', function (event) {
      flash(event.feature);
    });

    addRandomFeature()
    window.setInterval(addRandomFeature, 1500);
  }

  //定位（回到中心）
  location(point) {
    // var view = this.olmap.getView();
    // this.olmap.getView().animate({ // 只设置需要的属性即可
    //   center: point, // 中心点
    //   // center: getProjection(point, 'EPSG:4326'),
    //   zoom: view.getZoom(), // 缩放级别
    //   rotation: undefined, // 缩放完成view视图旋转弧度
    //   duration: 500 // 缩放持续时间，默认不需要设置
    // })
    this.olmap.getView().setCenter(point)
  }

  // 放大
  enlarge(n) {
    var view = this.olmap.getView();
    this.olmap.getView().animate({
      // center: point,
      zoom: view.getZoom() + n,
      rotation: undefined,
      duration: 500
    })
  }
  lessen(n) {
    var view = this.olmap.getView();
    this.olmap.getView().animate({
      // center: point, 
      zoom: view.getZoom() - n,
      rotation: undefined,
      duration: 500
    })
  }

  getImageLayer(url, extent) {
    var projection = new Projection({ // 定义坐标系
      code: 'xkcd-image',
      units: 'pixels',
      extent: extent
    })
    return new ImageLayer({
      source: new Static({
        url: url, // 地址
        projection: projection,
        imageExtent: extent
      })
    })
  }

  getTomcatTiledLayer(lyrId, tileUrl, zIndex) {
    const _this = this
    var projection = getProjection('EPSG:4326')
    // 原点
    var origin = map_config[map_location].origin
    // 分辨率
    var resolutions = map_config[map_location].resolutions
    // 地图范围
    var fullExtent = [map_config[map_location].full_Extent.xmin, map_config[map_location].full_Extent.ymin, map_config[map_location].full_Extent.xmax, map_config[map_location].full_Extent.ymax]
    var tileGrid = new WMTSTileGrid({
      tileSize: 256,
      origin: origin,
      extent: fullExtent,
      resolutions: resolutions
    })
    // 瓦片数据源
    var tileArcGISXYZ = new ImageArcGISRest({
      tileGrid: tileGrid,
      projection: projection,
      tileUrlFunction: function (tileCoord) {
        // 缩放级别
        var z = _this.zeroPad(tileCoord[0], 2, 10)
        // 瓦片行号
        var x = _this.zeroPad(tileCoord[1], 8, 16)
        // 瓦片列号
        var y = _this.zeroPad(-tileCoord[2] - 1, 8, 16)
        // 瓦片本地路径
        return tileUrl + 'L' + z + '/' + 'R' + y + '/' + 'C' + x + '.png'
      }
    })

    var layer = new TileLayer({
      layerName: lyrId,
      source: tileArcGISXYZ,
      zIndex: zIndex
    })
    return layer
  }

  getTiledXYZLayer(lyrId, url, zIndex, projection) {
    var layer = new TileLayer({
      zIndex: zIndex || 0,
      source: new XYZ({
        // crossOrigin: 'anonymous',
        projection: projection || 'EPSG:4326',
        url: url
      })
    })
    layer._id = lyrId
    return layer
  }

  getTiledLayer(lyrId, url, zIndex) {
    var projection = getProjection('EPSG:4326')
    var projectionExtent = projection.getExtent()
    var size = getWidth(projectionExtent) / 256
    var resolutions = new Array(14)
    var matrixIds = new Array(14)
    for (var z = 0; z <= 14; ++z) {
      resolutions[z] = size / Math.pow(2, z)
      matrixIds[z] = z
    }
    var layer = new TileLayer({
      zIndex: zIndex || 0,
      source: new WMTS({
        url: url,
        layer: lyrId.split('_')[0],
        format: 'tiles',
        tileGrid: new WMTSTileGrid({
          origin: getTopLeft(projectionExtent),
          resolutions: resolutions,
          matrixIds: matrixIds
        }),
        matrixSet: lyrId.split('_')[1],
        style: 'default'
      })
    })
    layer._id = lyrId
    return layer
  }

  addWmsTiledLayer(lyrId, url, zIndex) {
    // debugger
    // var projection = getProjection('EPSG:4326')
    // var projectionExtent = projection.getExtent()
    // var size = getWidth(projectionExtent) / 256
    // var resolutions = new Array(14)
    // var matrixIds = new Array(14)
    // for (var z = 0; z <= 14; ++z) {
    //   resolutions[z] = size / Math.pow(2, z)
    //   matrixIds[z] = z
    // }
    if (this.dynamicLayers[lyrId]) {
      this.olmap.removeLayer(this.dynamicLayers[lyrId])
      delete this.dynamicLayers[lyrId]
    }
    this.dynamicLayers[lyrId] = new TileLayer({
      zIndex: zIndex || 0,
      //extent:  [3.62891068888183E7,3907400.1902684523,3.6450050650878906E7,3944515.3072999995],
      source: new TileWMS({
        url: url,
        params: {
          'FORMAT': 'image/png',
          'VERSION': '1.1.1',
          'TILED': true
        },
        serverType: 'geoserver',
        // layer: lyrId.split('_')[0],

        // matrixSet: lyrId.split('_')[1],
        style: 'default'
      })
    })

    this.olmap.addLayer(this.dynamicLayers[lyrId])
    console.log(this.dynamicLayers)
    // layer._id = lyrId
    // return layer
  }

  getTiledArcgisLayer(lyrId, url, zIndex) {
    var layer = new TileLayer({
      zIndex: zIndex || 0,
      source: new TileArcGISRest({
        // crossOrigin: 'anonymous',
        url: url
      })
    })
    layer._id = lyrId
    return layer
  }

  addDynamicPointLayer(layer_name, data, xField, yField, valueField, options) {
    if (dynamicLayers[layer_name]) {
      this.olmap.removeLayer(dynamicLayers[layer_name])
      delete dynamicLayers[layer_name]
    }
    var layers = []
    for (var i = 0; i < options.styles.length; i++) {
      var vectorSource = new VectorSource({
        features: []
      })
      var layer = new VectorLayer({
        layerName: layer_name,
        declutter: options.declutter || false,
        source: vectorSource,
        zIndex: 100,
        style: options.styles[i]
      })
      layer.setVisible(options.styles[i].visible)
      layers.push(layer)
    }
    data.forEach(function (v) {
      var layer = layers[0]
      var vectorSource = layer.getSource()
      var feature = new Feature({ geometry: new Point([v[xField], v[yField]]) })
      if (!options.isIcon) v.color = options.styles[0].color
      feature.setProperties(v)
      vectorSource.addFeature(feature)
      layer.setSource(vectorSource)
      
    })

    dynamicLayers[layer_name] = new LayerGroup({
      layers: layers,
      visible: true
    })
    this.olmap.addLayer(dynamicLayers[layer_name])
  }

  addDynamicLayer(layer_name, sources, options) {
    if (dynamicLayers[layer_name]) {
      this.olmap.removeLayer(dynamicLayers[layer_name])
      delete dynamicLayers[layer_name]
    }
    var layers = []
    for (var i = 0; i < options.styles.length; i++) {
      var layer = new VectorSource({
        layerName: layer_name,
        source: sources[i],
        zIndex: 2,
        style: options.styles[i]
      })
      layer.setVisible(options.styles[i].visible)
      layers.push(layer)
    }
    options.id = layer_name + 'Legend'

   
    // addMapLegend(options)
    // reloadLegends()
    dynamicLayers[layer_name] = new LayerGroup({
      layers: layers,
      visible: true
    })
    this.olmap.addLayer(dynamicLayers[layer_name])
  }

  drawCircle(ctx, color) {
    ctx.fillStyle = color
    ctx.beginPath()
    ctx.arc(13, 13, 6, 0, Math.PI * 2, true)
    ctx.strokeStyle = '#c3c3c3'
    ctx.lineWidth = 1
    ctx.fill()
    ctx.stroke()
    ctx.closePath()
  }

  drawLine(ctx, color) {
    ctx.moveTo(0, 13) // 设置起点状态
    ctx.lineTo(25, 13) // 设置末端状态
    ctx.lineWidth = 3 // 设置线宽状态
    ctx.strokeStyle = color // 设置线的颜色状态
    ctx.stroke() // 进行绘制
  }

  // mouseover事件
  mapMouseover() {
    selectPointerMove = new Select({
      condition: pointerMove,
      filter: function (feature, layer) {
        var ifFilter = true
        if (layer && (layer.getProperties())) { // 过滤图层
          // console.log('olmap--------',layer.getProperties())
          if (layer.getProperties().layerName !== 'riverLayer' && layer.getProperties().layerName !== 'basinTileLayer' && layer.getProperties().layerName !== 'basinLayer' && layer.getProperties().layerName !== 'areaDrawLayer' && layer.getProperties().layerName !== 'lineDrawLayer') {
            ifFilter = true
          } else {
            ifFilter = false
          }
        }
        return ifFilter
      }
    })
    this.olmap.removeInteraction(selectPointerMove)
    this.olmap.addInteraction(selectPointerMove)
    const _this = this
    selectPointerMove.on('select', function (e) {
      var feature = e.target.getFeatures().item(0)
      if (feature) {
        var properties = feature.getProperties()
        if (!!properties.xField && !!properties.yField) {
          var str = `这是一个点信息<hr /">${properties.xField},${properties.yField}`
          // "<table style='font-size: 12px;width:100%;text-align:left;'><tr>" +
          //   "<td  align='left' style='padding-left: 2px;font-weight:bold;width:40px;'>站&nbsp;&nbsp;&nbsp;&nbsp;名：</td>" +
          //   "<td  style='padding-right:2px;'><font>" + (properties.stnm || '') + '</font></td>' +
          //   '</tr>' +
          //   '<tr>' +
          //   "<td  align='left' style='padding-left: 2px;font-weight:bold;'>站&nbsp;&nbsp;&nbsp;&nbsp;码：</td>" +
          //   "<td  style='padding-right:2px;'><font>" + properties.stcd + '</font></td>' +
          //   '</tr>' +
          //   '<tr>' +
          //   "<td   align='left'  style='padding-left: 2px;font-weight:bold;'>类&nbsp;&nbsp;&nbsp;&nbsp;型：</td>" +
          //   "<td   style='padding-right:2px;'><font>" + properties.stct + '</font></td>' +
          //   '</tr>' +
          //   '<tr>' +
          //   "<td  align='left'  style='padding-left: 2px;font-weight:bold;'>经&nbsp;&nbsp;&nbsp;&nbsp;度：</td>" +
          //   "<td  style='padding-right:2px;'><font>" + parseFloat(properties.lgtd).toFixed(2) + '</font></td>' +
          //   '</tr>' +
          //   '<tr>' +
          //   "<td  align='left'  style='padding-left: 2px;font-weight:bold;'>纬&nbsp;&nbsp;&nbsp;&nbsp;度：</td>" +
          //   "<td  style='padding-right:2px;'><font>" + parseFloat(properties.lttd).toFixed(2) + '</font></td>' +
          //   '</tr>' +
          //   '<tr>' +
          //   "<td  align='left'  style='padding-left: 2px;font-weight:bold;'>地&nbsp;&nbsp;&nbsp;&nbsp;址：</td>" +
          //   "<td  style='padding-right:2px;'><font>" + (properties.stlc || '') + '</font></td>' +
          //   '</tr>' +
          //   '</table>'
          _this.showPopUp(properties.xField, properties.yField, str)
        }
      } else {
        // $('#popup').hide()
      }
    })
  }

  // 鼠标点击事件

  mapClick(callback) {
    selectMouseClick = new Select({
      features: selectedFeatures
    })
    this.olmap.addInteraction(selectMouseClick)
    selectMouseClick.on('select', function(e) {
      var feature = e.target.getFeatures().item(0)
      if (feature) {
        var properties = feature.getProperties()
        var layer = e.target.getLayer(feature)
        if (layer !== null && layer !== mapMeasureTool.vector && layer !== areaDrawTool.vector && layer !== lineDrawTool.vector && layer !== pointDrawTool.vector && layer !== squareDrawTool.vector && layer !== circleDrawTool.vector) {
          callback(properties)
        }
      }
      selectedFeatures.clear() // 避免一个要素多次点击无效的问题
    })
  }

  loadMapFlashMarker(properties) {
    var name = ''
    properties.forEach(function ( v) {
      if (v.toLowerCase().indexOf('cd') !== -1) name = v
    })
    if (name === '') return
    if (!mapFalshMarker) {
      // mapFalshMarker = new FlashMarker(map, [{
      //   name: name,
      //   lnglat: [properties.lgtd, properties.lttd],
      //   color: '#FF6100',
      //   type: 'circle',
      //   speed: 0.2
      // }])
    } else {
      mapFalshMarker.setMarkers([{
        name: name,
        lnglat: [properties.lgtd, properties.lttd],
        color: '#FF6100',
        type: 'circle',
        speed: 0.2
      }])
    }
  }

  /**
   * @param longitude 纬度
   * @param latitude 经度
   * @param htmlStr html字符串
   * @param htmlStr 标题
   */
  // showPopUp(longitude, latitude, htmlStr) {
  //   var container = document.getElementById('popup') // 弹出框
  //   $('#popup').show()
  //   var content = document.getElementById('popup-content')
  //   var overlay = new Overlay({
  //     element: container,
  //     autoPan: true,
  //     autoPanAnimation: {
  //       duration: 250 // 当Popup超出地图边界时，为了Popup全部可见，地图移动的速度.
  //     }
  //   })
  //   content.innerHTML = htmlStr
  //   overlay.setPosition([longitude, latitude])
  //   this.olmap.addOverlay(overlay)
  // }

  // 进制转换并补齐Arcgis Server目录和名称前面的0
  zeroPad(num, len, radix) {
    var str = num.toString(radix || 10)
    while (str.length < len) {
      str = '0' + str
    }
    return str
  }

  formatLegendText(text) {
    if (text.length > 6) {
      return '<span title="' + text + '">' + text.substring(0, 4) + '...</span>'
    }
    return text
  }

  /**
   * Format length output.
   * @param {ol.geom.LineString} line The line.
   * @return {string} The formatted length.
   */
  formatLength(line) {
    var length = getLength(line, {
      projection: 'EPSG:4326'
    })
    var output
    if (length > 100) {
      output = (Math.round(length / 1000 * 100) / 100) +
        ' ' + 'km'
    } else {
      output = (Math.round(length * 100) / 100) +
        ' ' + 'm'
    }
    return output
  }

  /**
   * Format area output.
   * @param {ol.geom.Polygon} polygon The polygon.
   * @return {string} Formatted area.
   */
  formatArea(polygon) {
    var area = getArea(polygon, {
      projection: 'EPSG:4326'
    })
    var output
    if (area > 10000) {
      output = (Math.round(area / 1000000 * 100) / 100) +
        ' ' + 'km<sup>2</sup>'
    } else {
      output = (Math.round(area * 100) / 100) +
        ' ' + 'm<sup>2</sup>'
    }
    return output
  }

  /**
   * Creates a new help tooltip
   */
  createHelpTooltip() {
    if (mapMeasureTool.helpTooltipElement) {
      mapMeasureTool.helpTooltipElement.parentNode.removeChild(mapMeasureTool.helpTooltipElement)
    }
    mapMeasureTool.helpTooltipElement = document.createElement('div')
    mapMeasureTool.helpTooltipElement.className = 'tooltip hidden'
    mapMeasureTool.helpTooltip = new Overlay({
      element: mapMeasureTool.helpTooltipElement,
      offset: [15, 0],
      positioning: 'center-left'
    })
    this.olmap.addOverlay(mapMeasureTool.helpTooltip)
  }

  /**
   * Creates a new measure tooltip
   */
  createMeasureTooltip() {
    if (mapMeasureTool.measureTooltipElement) {
      mapMeasureTool.measureTooltipElement.parentNode.removeChild(mapMeasureTool.measureTooltipElement)
    }
    mapMeasureTool.measureTooltipElement = document.createElement('div')
    mapMeasureTool.measureTooltipElement.className = 'tooltip tooltip-measure'
    mapMeasureTool.measureTooltip = new Overlay({
      element: mapMeasureTool.measureTooltipElement,
      offset: [0, -15],
      positioning: 'bottom-center'
    })
    this.olmap.addOverlay(mapMeasureTool.measureTooltip)
  }

  pointerMoveHandler(evt) {
    if (evt.dragging) {
      return
    }
    /** @type {string} */
    var helpMsg = '点击开始测量'
    if (mapMeasureTool.sketch) {
      var geom = (mapMeasureTool.sketch.getGeometry())
      if (geom instanceof Polygon) {
        helpMsg = mapMeasureTool.continuePolygonMsg
      } else if (geom instanceof LineString) {
        helpMsg = mapMeasureTool.continueLineMsg
      }
    }

    mapMeasureTool.helpTooltipElement.innerHTML = helpMsg
    mapMeasureTool.helpTooltip.setPosition(evt.coordinate)

    mapMeasureTool.helpTooltipElement.classList.remove('hidden')
  }

  addInteraction(type) {
    const _this = this
    // if (mapMeasureTool.draw) {
    //   _this.removeMapMeasureTool()
    // }
    mapMeasureTool.drawType = type
    this.olmap.on('pointermove', this.pointerMoveHandler)
    mapMeasureTool.draw = new Draw({
      source: mapMeasureTool.source,
      type: type,
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(0, 0, 0, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new CircleStyle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgba(0, 0, 0, 0.7)'
          }),
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    })
    this.olmap.addInteraction(mapMeasureTool.draw)

    this.createMeasureTooltip()
    this.createHelpTooltip()

    let listener

    mapMeasureTool.draw.on('drawstart', function (evt) {
      // set mapMeasureTool.sketch
      mapMeasureTool.sketch = evt.feature

      /** @type {ol.Coordinate|undefined} */
      var tooltipCoord = evt.coordinate

      listener = mapMeasureTool.sketch.getGeometry().on('change', function (evt1) {
        var geom = evt1.target
        var output

        if (geom instanceof Polygon) {
          output = _this.formatArea(geom)
          tooltipCoord = geom.getInteriorPoint().getCoordinates()
        } else if (geom instanceof LineString) {
          output = _this.formatLength(geom)
          tooltipCoord = geom.getLastCoordinate()
        }
        mapMeasureTool.measureTooltipElement.innerHTML = output
        mapMeasureTool.measureTooltip.setPosition(tooltipCoord)
      })
    }, this)

    mapMeasureTool.draw.on('drawend', function (evt) {
      if (evt.feature.values_.geometry instanceof Point && mapMeasureTool.drawType === 'Point') {
        const points = evt.feature.values_.geometry.flatCoordinates
        const str = '经度：' + points[0] + '</br>纬度：' + points[1]
        mapMeasureTool.measureTooltipElement.innerHTML = str
        mapMeasureTool.measureTooltip.setPosition(points)
     
      }
      mapMeasureTool.measureTooltipElement.className = 'tooltip tooltip-static'
      mapMeasureTool.measureTooltip.setOffset([0, -7])
      // unset mapMeasureTool.sketch

      // unset tooltip so that a new one can be created
      // mapMeasureTool.measureTooltipElement = null
      _this.removeMapMeasureTool()
      
      unByKey(listener)
    }, this)
  }

  removeMapMeasureTool() {
    const _this = this
    if (mapMeasureTool.draw) {
      this.olmap.removeInteraction(mapMeasureTool.draw)

      this.olmap.un('pointermove', _this.pointerMoveHandler)
 
      mapMeasureTool.helpTooltipElement.innerHTML = ''
      // mapMeasureTool.helpTooltipElement = null
      mapMeasureTool.measureTooltipElement = null
    }
  }
  clearDraw(){
    mapMeasureTool.source.clear()
    // $('.tooltip').remove()
    // mapMeasureTool.measureTooltipElement = null
    mapMeasureTool.helpTooltipElement = null
    pointDrawTool.source.clear()
    circleDrawTool.source.clear()
    lineDrawTool.source.clear()
    squareDrawTool.source.clear()
    areaDrawTool.source.clear()
  }
  addPointDrawTool(callback) {
    if (pointDrawTool.draw) {
      this.removeMapMeasureTool()
    }
    const _this = this
    this.clearPointDraw()
    pointDrawTool.draw = new Draw({
      source: pointDrawTool.source,
      type: 'Point',
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(0, 0, 0, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new CircleStyle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgba(0, 0, 0, 0.7)'
          }),
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    })
    this.olmap.addInteraction(pointDrawTool.draw)
    pointDrawTool.draw.on('drawstart', function () {
      _this.clearPointDraw()
    }, _this)
    pointDrawTool.draw.on('drawend', function (evt) {
      console.log(evt)
      if (!!evt.feature && !!callback ) callback(evt.feature.getGeometry().getCoordinates())
      _this.removePointDrawTool()
    }, _this)
  }
  clearPointDraw() {
    pointDrawTool.source.clear()
  }
  removePointDrawTool() {
    if (pointDrawTool.draw) {
      this.olmap.removeInteraction(pointDrawTool.draw)
    }
  }
  addSquareDrawTool(callback) {
    if (squareDrawTool.draw) {
      this.removeMapMeasureTool()
    }
    const _this = this
    this.clearSquareDraw()
    squareDrawTool.draw = new Draw({
      source: squareDrawTool.source,
      type: 'Circle',
      geometryFunction: createBox(),
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(0, 0, 0, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new CircleStyle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgba(0, 0, 0, 0.7)'
          }),
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    })
    this.olmap.addInteraction(squareDrawTool.draw)
    squareDrawTool.draw.on('drawstart', function () {
      _this.clearSquareDraw()
    }, _this)
    squareDrawTool.draw.on('drawend', function (evt) {
      if (!!evt.feature && !!callback) callback(evt.feature.getGeometry().getCoordinates())
      _this.removeSquareDrawTool()
    }, _this)
  }
  clearSquareDraw() {
    squareDrawTool.source.clear()
  }
  removeSquareDrawTool() {
    if (squareDrawTool.draw) {
      this.olmap.removeInteraction(squareDrawTool.draw)
    }
  }
  addCircleDrawTool(callback) {
    if (circleDrawTool.draw) {
      this.removeMapMeasureTool()
    }
    const _this = this
    this.clearCircleDraw()
    circleDrawTool.draw = new Draw({
      source: circleDrawTool.source,
      type: 'Circle',

      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(0, 0, 0, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new CircleStyle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgba(0, 0, 0, 0.7)'
          }),
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    })
    this.olmap.addInteraction(circleDrawTool.draw)
    circleDrawTool.draw.on('drawstart', function () {
      _this.clearCircleDraw()
    }, _this)
    circleDrawTool.draw.on('drawend', function (evt) {
      const center = evt.feature.getGeometry().getCenter()
      const radius = evt.feature.getGeometry().getRadius()
      // console.log(_this.unit)
      // let units
      // if(_this.unit=='m'){
      //   units='meters'
      // }else if(_this.unit=='km'){
      //   units='kilometers'
      // }
      // const options = { steps: 10, units: units }

      // var circle = turf.circle(center, radius, options)
      var circle = new Circle(center, radius);
      var polygon = fromCircle(circle)
      var circleFeature = new Feature({
        geometry: polygon,
      });
      if (!!evt.feature && !!callback ) callback(circleFeature.getGeometry().flatCoordinates)
      _this.removeCircleDrawTool()
    }, _this)
  }
  clearCircleDraw() {
    circleDrawTool.source.clear()
  }
  removeCircleDrawTool() {

    if (circleDrawTool.draw) {
      this.olmap.removeInteraction(circleDrawTool.draw)

    }
  }
  addLineDrawTool(callback) {
    if (lineDrawTool.draw) {
      this.removeMapMeasureTool()
    }
    const _this = this
    this.clearLineDraw()
    lineDrawTool.draw = new Draw({
      source: lineDrawTool.source,
      type: 'LineString',
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(0, 0, 0, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new CircleStyle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgba(0, 0, 0, 0.7)'
          }),
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    })
    this.olmap.addInteraction(lineDrawTool.draw)
    lineDrawTool.draw.on('drawstart', function () {
      _this.clearLineDraw()
    }, _this)
    lineDrawTool.draw.on('drawend', function (evt) {
      if (!!evt.feature && !!callback) callback(evt.feature.getGeometry().getCoordinates())
      _this.removeLineDrawTool()
    }, _this)
  }

  addAreaDrawTool(callback) {
    if (areaDrawTool.draw) {
      this.removeMapMeasureTool()
    }
    this.clearAreaDraw()
    const _this = this
    areaDrawTool.draw = new Draw({
      source: areaDrawTool.source,
      type: 'Polygon',
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(0, 0, 0, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new CircleStyle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgba(0, 0, 0, 0.7)'
          }),
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    })
    this.olmap.addInteraction(areaDrawTool.draw)
    areaDrawTool.draw.on('drawstart', function () {
      _this.clearAreaDraw()
    }, _this)
    areaDrawTool.draw.on('drawend', function (evt) {
      if (!!evt.feature && !!callback ) callback(evt.feature.getGeometry().getCoordinates())
      _this.removeAreaDrawTool()
    }, _this)
  }
  removeAreaDrawTool() {
    if (areaDrawTool.draw) {
      this.olmap.removeInteraction(areaDrawTool.draw)
    }
  }

  clearAreaDraw() {
    areaDrawTool.source.clear()
  }

  addAreaDrawPolygon(coordinates) {
    var feature = new Feature({
      geometry: new Polygon([coordinates])
    })
    areaDrawTool.source.addFeature(feature)
  }

  zoomToAreaDrawLayer() {
    this.zoomToExtent(areaDrawTool.source.getExtent())
  }

  zoomToExtent(extent) {
    var r = this.olmap.getView().getResolutionForExtent(extent, this.olmap.getSize())
    this.olmap.getView().setResolution(r)
    this.olmap.getView().setCenter(getCenter(extent))
  }

  removeLineDrawTool() {
    if (lineDrawTool.draw) {
      this.olmap.removeInteraction(lineDrawTool.draw)
    }
  }

  clearLineDraw() {
    lineDrawTool.source.clear()
  }

  addLineDrawPolygon(coordinates) {
    var feature = new Feature({
      geometry: new LineString([coordinates])
    })
    lineDrawTool.source.addFeature(feature)
  }

  zoomToLineDrawLayer() {
    this.zoomToExtent(lineDrawTool.source.getExtent())
  }

  zoomToPoint(x, y) {
    this.olmap.getView().setCenter([x, y])
  }

  swipeTile(aerial) {
    const _this = this
    const swipe = document.getElementById('swipe')
    aerial.on('prerender', function (event) {
      const ctx = event.context
      const mapSize = _this.olmap.getSize()
      const width = mapSize[0] * (swipe.value / 100)
      const tl = getRenderPixel(event, [width, 0])
      const tr = getRenderPixel(event, [mapSize[0], 0])
      const bl = getRenderPixel(event, [width, mapSize[1]])
      const br = getRenderPixel(event, mapSize)

      ctx.save()
      ctx.beginPath()
      ctx.moveTo(tl[0], tl[1])
      ctx.lineTo(bl[0], bl[1])
      ctx.lineTo(br[0], br[1])
      ctx.lineTo(tr[0], tr[1])
      ctx.closePath()
      ctx.clip()
    })

    aerial.on('postrender', function (event) {
      const ctx = event.context
      ctx.restore()
    })
    swipe.addEventListener(
      'input',
      function () {
        _this.olmap.render()
      },
      false
    )
  }
  copyMap(id) {

    let _this = this
    // this.osm = new TileLayer({
    //   source: new OSM()
    // })
    let grouplayers = []
    let center
    grouplayers.push(this.osm)
    let copyMap = new Map({
      logo: false,
      target: id,
      layers: [],
      // overlays: [overlay],
      controls: defaultControls({
        attribution: false,
        zoom: false,
        rotate: false
      }).extend([
        new MousePosition({
          className: 'ol-mouse-pos',
          coordinateFormat: createStringXY(2),
          undefinedHTML: ''
        })
      ]),
      view: _this.mapView
    })
    return copyMap
  }
  addWmsTwoTiledLayer(copyMap, lyrId, url, zIndex, copyTwoLayers) {
    if (copyTwoLayers[lyrId]) {
      copyMap.removeLayer(copyTwoLayers[lyrId])
      delete copyTwoLayers[lyrId]
    }
    copyTwoLayers[lyrId] = new TileLayer({
      zIndex: zIndex || 0,
      //extent:  [3.62891068888183E7,3907400.1902684523,3.6450050650878906E7,3944515.3072999995],
      source: new TileWMS({
        url: url,
        params: {
          'FORMAT': 'image/png',
          'VERSION': '1.1.1',
          'TILED': true
        },
        serverType: 'geoserver',
        // layer: lyrId.split('_')[0],
        // matrixSet: lyrId.split('_')[1],
        style: 'default'
      })
    })
    copyMap.addLayer(copyTwoLayers[lyrId])
    // layer._id = lyrId
    // return layer
  }

  printMap(id) {
    let canvas = document.querySelector('canvas')
    console.log(canvas)
    html2canvas(this.olmap.getViewport(), exportOptions).then(canvas => {
      var img = canvas.toDataURL('image/jpeg')
      // window.open(img);
      let elink = document.createElement("a");
      // 设置下载文件名
      elink.download = "";
      elink.style.display = "none";
      // let blob = new Blob([content], {type: "image/png"})
      elink.href = img;
      document.body.appendChild(elink);
      elink.click();
      document.body.removeChild(elink);
      // if (navigator.msSaveBlob) {
      //   navigator.msSaveBlob(canvas.msToBlob(), "map.jpeg");
      // } else {
      //   canvas.toBlob(function(blob) {
      //     FileSaver.saveAs(blob, "map.jpeg");
      //   })
      // }
    });

  }
}